/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.business.fee.core.service.query;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import info.peigen.hotpot.business.fee.core.domain.action.FeeConverter;
import info.peigen.hotpot.business.fee.core.repository.entity.FeeRuleEntity;
import info.peigen.hotpot.business.fee.facade.enums.FeeProductCode;
import info.peigen.hotpot.business.fee.facade.query.FeeRuleQueryServiceFacade;
import info.peigen.hotpot.business.fee.facade.query.order.QueryDefaultFeeRuleOrder;
import info.peigen.hotpot.business.fee.facade.query.order.QueryFeeRuleListOrder;
import info.peigen.hotpot.business.fee.facade.query.order.QueryFeeRuleOrder;
import info.peigen.hotpot.business.fee.facade.query.result.QueryDefaultFeeRuleResult;
import info.peigen.hotpot.business.fee.facade.query.result.QueryFeeRuleListResult;
import info.peigen.hotpot.business.fee.facade.query.result.QueryFeeRuleResult;
import info.peigen.hotpot.business.fee.facade.query.result.info.QueryFeeRuleResultInfo;
import info.peigen.hotpot.common.core.enums.Currency;
import info.peigen.hotpot.common.core.result.ResultCode;
import info.peigen.hotpot.common.service.base.ServiceQuery;
import info.peigen.hotpot.common.service.base.ServiceQueryContext;
import info.peigen.hotpot.common.service.base.exception.BusinessException;
import org.noear.solon.annotation.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <b>(FeeRuleQueryService)</b>
 *
 * @author LiDaHai
 * @version 1.0.0
 * @since 2022/8/19
 */
@Component
public class FeeRuleQueryService extends AbstractFeeRuleQueryService implements FeeRuleQueryServiceFacade {
    @Override
    public QueryFeeRuleResult queryFeeRule(QueryFeeRuleOrder order) {
        ServiceQueryContext serviceContext = ServiceQueryContext.builder().order(order).result(new QueryFeeRuleResult()).build();
        query(serviceContext, new ServiceQuery() {
            @Override
            public void query(ServiceQueryContext serviceContext) {
                //query entity
                FeeRuleEntity entity = feeRuleRepository.queryFeeRule(order.getStationParentId(), order.getPartnerId(), order.getCustomerId(),
                        FeeProductCode.Recharge, Currency.CNY);
                serviceContext.setEntity(entity);
            }

            @Override
            public void convert(ServiceQueryContext serviceContext) {
                //entity convert to info
                FeeRuleEntity entity = (FeeRuleEntity) serviceContext.getEntity();
                Assert.notNull(entity, () -> new BusinessException(ResultCode.FAILURE, "费用规则查询失败![FeeType]=" + order.getType()));
                QueryFeeRuleResultInfo info = FeeConverter.convertQueryFeeRuleInfo(entity);
                ((QueryFeeRuleResult) serviceContext.getResult()).fromSuccess(info);
            }
        });
        return (QueryFeeRuleResult) serviceContext.getResult();
    }

    @Override
    public QueryFeeRuleListResult queryFeeRuleList(QueryFeeRuleListOrder order) {
        ServiceQueryContext serviceContext = ServiceQueryContext.builder().order(order).result(new QueryFeeRuleListResult()).build();
        query(serviceContext, new ServiceQuery() {
            @Override
            public void query(ServiceQueryContext serviceContext) {
                //query entity
                List<FeeRuleEntity> feeRuleList = feeRuleRepository.listByPartnerIds(order.getPartnerIds(), order.getCode());
                List<FeeRuleEntity> result      = Lists.newArrayList();
                Map<String, FeeRuleEntity> feeRuleEntityMap = feeRuleList.stream().collect(Collectors.toMap(each -> {
                    if (StrUtil.isNotEmpty(each.getAccountId())) {
                        return "Account:" + each.getAccountId();
                    } else if (StrUtil.isNotEmpty(each.getStationParentId())) {
                        return "StationParent:" + each.getStationParentId();
                    } else {
                        return "Partner:" + each.getPartnerId();
                    }
                }, entity -> entity));
                order.getStationParentIds();
                for (int i = 0; i < order.getStationParentIds().size(); i++) {
                    String stationParentId = order.getStationParentIds().get(i);
                    if (feeRuleEntityMap.containsKey("StationParent:" + stationParentId)) {
                        result.add(feeRuleEntityMap.get("StationParent:" + stationParentId));
                    } else {
                        String partnerId = order.getPartnerIds().get(i);
                        result.add(feeRuleEntityMap.get("Partner:" + partnerId));
                    }
                }
                serviceContext.setEntities(result);
            }

            @Override
            public void convert(ServiceQueryContext serviceContext) {
                //entity convert to info
                List<FeeRuleEntity> entities = serviceContext.getEntities();
                ((QueryFeeRuleListResult) serviceContext.getResult()).fromSuccess(FeeConverter.convertQueryFeeRuleInfo(entities));
            }
        });
        return (QueryFeeRuleListResult) serviceContext.getResult();
    }

    @Override
    public QueryDefaultFeeRuleResult queryDefaultFeeRule(QueryDefaultFeeRuleOrder order) {
        ServiceQueryContext serviceContext = ServiceQueryContext.builder().order(order).result(new QueryDefaultFeeRuleResult()).build();
        query(serviceContext, new ServiceQuery() {
            @Override
            public void query(ServiceQueryContext serviceContext) {
                //query entity
                FeeRuleEntity entity = feeRuleRepository.queryFeeRule(null, order.getPartnerId(), null, FeeProductCode.Recharge, Currency.CNY);
                serviceContext.setEntity(entity);
            }

            @Override
            public void convert(ServiceQueryContext serviceContext) {
                //entity convert to info
                FeeRuleEntity entity = (FeeRuleEntity) serviceContext.getEntity();
                Assert.notNull(entity, () -> new BusinessException(ResultCode.FAILURE, "费用规则查询失败![FeeType]=" + order.getType()));
                QueryFeeRuleResultInfo info = FeeConverter.convertQueryFeeRuleInfo(entity);
                ((QueryDefaultFeeRuleResult) serviceContext.getResult()).fromSuccess(info);
            }
        });
        return (QueryDefaultFeeRuleResult) serviceContext.getResult();
    }
}